package com.weiawei.computer;

import com.weiawei.Model.Chess;
import com.weiawei.Model.ChessCoord;
import com.weiawei.Model.Point;
import com.weiawei.ui.ChooseLevel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Computer {
    private int scores;
    private ChessCoord coord = new ChessCoord();
    private final int[][] PlayerPointScore = new int[19][19];
    private final int[][] ComputerPointScore = new int[19][19];
    Point pointfortree;

    /**
     * 从PVEChessBoard到电脑算法的入口函数
     *
     * @param comrole 电脑棋子颜色
     * @param level   电脑难度
     * @param chess   棋盘
     */
    public ChessCoord computePos(int comrole, int[][] chess, int level) {
        if (level == ChooseLevel.EasyField) {
            if (comrole == Chess.white) {
                countMaxLines_primary(chess, Chess.black);
                return coord;
            } else {
                countMaxLines_primary(chess, Chess.white);
                return coord;
            }
        }
        //中级
        else if (level == ChooseLevel.middleField) {
            if (comrole == Chess.white) {
                countMaxLines_medium(chess, Chess.black);
                return coord;
            } else {
                countMaxLines_medium(chess, Chess.white);
                return coord;
            }

        }
        //高级
        else if (level == ChooseLevel.highestField) {
            countMaxLines_senior(chess, comrole);
            return coord;
        }
        return coord;
    }

    /**
     * 中等难度电脑计算最适合的位置返回给computePos
     *
     * @param role  玩家颜色
     * @param chess 棋盘
     */
    public void countMaxLines_medium(int[][] chess, int role)//这里的role是玩家颜色
    {
        int comrole;
        if (role == Chess.black)
            comrole = Chess.white;
        else
            comrole = Chess.black;
        ChessCoord playerCoord = new ChessCoord();
        ChessCoord computerCoord = new ChessCoord();
        int x, y;
        for (x = 0; x < 19; x++) {
            for (y = 0; y < 19; y++) {
                if (chess[x][y] == Chess.noChess) {
                    countEveryPos_medium_defence(x, y, chess, role);
                    PlayerPointScore[x][y] = scores;
                    countEveryPos_medium_attack(x, y, chess, comrole);
                    ComputerPointScore[x][y] = scores;
                } else {
                    PlayerPointScore[x][y] = 0;
                    ComputerPointScore[x][y] = 0;
                }
            }
        }
        if (findBestPos(PlayerPointScore, playerCoord) >= findBestPos(ComputerPointScore, computerCoord)) {
            coord = playerCoord;//防守
        } else {
            coord = computerCoord;//进攻
        }
    }

    /**
     * 中等难度电脑防守战略
     * 给每一个空位置根据周围的旗子情况打防守分，分数越高说明该点的防守必要性越高
     *
     * @param count    这个棋形有多少个棋子连在一起
     * @param i        有没有受到电脑棋子堵住，只有一端堵住i为1，两端都堵住i为2
     * @param countTwo 这个棋形存不存在活2（中等电脑和简单电脑的为一区分在于中等电脑对双活2的危险情况进行了进一步判断）
     */
    public void mark_medium_defence(int count, int i, int countTwo)//role是玩家颜色
    {
        if (count == 1) {
            scores = scores + 10;
        }
        //活二
        else if (count == 2 && i == 0 && countTwo <= 1) {
            scores = scores + 1400;
            System.out.println("玩家活二" + scores);
        }

        //冲二
        else if (count == 2 && i == 1) {
            scores = scores + 50;
            System.out.println("冲二" + scores);
        }
        //双活二
        else if (count == 2 && i == 0 && countTwo > 1) {
            scores = scores + 5000;
            System.out.println("玩家双活二" + scores);
        }
        //活三
        else if (count == 3 && i == 0) {
            scores = scores + 10000;
            System.out.println("玩家活三" + scores);
        }
        //冲三
        else if (count == 3 && i == 1) {
            scores = scores + 2000;
            System.out.println("玩家冲三" + scores);
        }
        //活四
        else if (count == 4 && i == 0) {
            scores = scores + 200000;
            System.out.println("玩家活四" + scores);
        }
        //冲四
        else if (count == 4 && i == 1 || count == 4 && i == 2) {
            scores = scores + 100000;
            System.out.println("玩家冲四" + scores);
        } else if (count == 5) {
            scores = scores + 1000000;
        }
    }

    /**
     * 中等难度电脑进攻战略（）
     * 给每一个空位置根据周围的旗子情况打进攻分，分数越高说明该点的进攻效果越好
     *
     * @param count    这个棋形有多少个电脑棋子连在一起
     * @param i        有没有受到玩家棋子堵住，只有一端堵住i为1，两端都堵住i为2
     * @param countTwo 这个棋形存不存在活2（中等电脑和简单电脑的为一区分在于中等电脑对双活2的危险情况进行了进一步判断）
     */
    public void mark_medium_attack(int count, int i, int countTwo)//role是玩家颜色
    {
        if (count == 1) {
            scores = scores + 10;
        }
        //活二
        else if (count == 2 && i == 0 && countTwo <= 1) {
            scores = scores + 4400;
            System.out.println("电脑活二" + scores);
        }
        //冲二
        else if (count == 2 && i == 1) {
            scores = scores + 100;
            System.out.println("电脑冲二" + scores);
        }
        //双活二
        else if (count == 2 && i == 0 && countTwo > 1) {
            scores = scores + 40000;
            System.out.println("双活二" + scores);
        } else if (count == 3 && i == 0) {
            scores = scores + 80000;
            System.out.println("电脑活三" + scores);
        }
        //冲三
        else if (count == 3 && i == 1) {
            scores = scores + 10000;
            System.out.println("电脑冲三" + scores);
        } else if (count == 4 && i == 0) {
            scores = scores + 990000;
            System.out.println("电脑活四" + scores);
        }
        //黑子活四
        //冲四
        else if (count == 4 && i == 1 || count == 4 && i == 2) {
            scores = scores + 987000;
            System.out.println("电脑冲四" + scores);
        } else if (count == 5) {
            scores = scores + 1000000;
        }
    }

    /**
     * 给空棋盘进行打分
     * 此函数运用于所有难度的人机
     *
     * @param x 棋盘位置的横坐标
     * @param y 棋盘位置的纵坐标
     */
    public void basicScore(int x, int y) {
        int temp = 25;
        int a, b;
        if (x >= 9)
            a = x - 9;
        else
            a = 9 - x;
        if (y >= 9)
            b = y - 9;
        else
            b = 9 - y;
        scores += (temp - a - b);
        //保证中心分数最高
    }

    /**
     * 中等难度电脑防守战略
     * 统计玩家某个空位上对应的周围棋局的情况，有没有形成特殊的棋形
     *
     * @param x     该位置的横坐标
     * @param y     该位置的纵坐标
     * @param chess int二维数组表示的棋盘
     * @param role  玩家棋子颜色
     */
    public void countEveryPos_medium_defence(int x, int y, int[][] chess, int role)//role是玩家颜色,当传入comrole时表示机器人
    {
        scores = 0;
        basicScore(x, y);
        //countTwo代表有一个坐标向八个方向数 两个连一起的个数
        int matchRole, startX = x, startY = y,
                count = 0, up = 0, down = 0, left = 0, right = 0,
                leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0, countTwo = 0;
        if (role == Chess.black) {
            matchRole = Chess.white;
        } else {
            matchRole = Chess.black;
        }
        //竖直方向上判断输赢
        while (true) {
            //向上判断
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || y < 0) {
                up++;
                break;
            } else {
                break;
            }
        }
        y = startY;
        while (true) {
            //向下判断
            y = y + 1;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || y >= 19) {
                down++;
                break;
            } else {
                break;
            }
        }
        //此处代表在上下方向有二连 或者 夹了一个空子两边各有一个棋子 并且两端没有其他子挡住
        if (count == 2 && (up + down == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_defence(count, up + down, countTwo);

        //水平方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左判断
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0) {
                left++;
                break;
            } else {
                break;
            }
        }//向左
        x = startX;
        while (true) {
            //向右判断
            x++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19) {
                right++;
                break;
            } else {
                break;
            }
        }//向右
        if (count == 2 && (left + right == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_defence(count, left + right, countTwo);

        //右倾斜方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左上判断
            y--;
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0 || y < 0) {
                leftUp++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右下判断
            x++;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19 || y >= 19) {
                rightDown++;
                break;
            } else {
                break;
            }
        }
        if (count == 2 && (leftUp + rightDown == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_defence(count, leftUp + rightDown, countTwo);

        //左倾斜方向判断
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左下判断
            x--;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0 || y >= 19) {
                leftDown++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右上判断
            x++;
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19 || y < 0) {
                rightUp++;
                break;
            } else {
                break;
            }
        }
        if (count == 2 && (leftDown + rightUp == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_defence(count, leftDown + rightUp, countTwo);
    }

    /**
     * 中等难度电脑进攻战略
     * 统计电脑某个空位上对应的周围棋局的情况，有没有形成特殊的棋形
     *
     * @param x     该位置的横坐标
     * @param y     该位置的纵坐标
     * @param chess int二维数组表示的棋盘
     * @param role  电脑棋子颜色
     */
    public void countEveryPos_medium_attack(int x, int y, int[][] chess, int role)//role是玩家颜色,当传入comrole时表示机器人
    {
        scores = 0;
        basicScore(x, y);
        //countTwo代表有一个坐标向八个方向数 两个连一起的个数
        int matchRole, startX = x, startY = y,
                count = 0, up = 0, down = 0, left = 0, right = 0,
                leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0, countTwo = 0;
        if (role == Chess.black) {
            matchRole = Chess.white;
        } else {
            matchRole = Chess.black;
        }
        //竖直方向上判断输赢
        while (true) {
            //向上判断
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || y < 0) {
                up++;
                break;
            } else {
                break;
            }
        }
        y = startY;
        while (true) {
            //向下判断
            y = y + 1;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || y >= 19) {
                down++;
                break;
            } else {
                break;
            }
        }
        //此处代表在上下方向有二连 或者 夹了一个空子两边各有一个棋子 并且两端没有其他子挡住
        if (count == 2 && (up + down == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_attack(count, up + down, countTwo);

        //水平方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左判断
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0) {
                left++;
                break;
            } else {
                break;
            }
        }//向左
        x = startX;
        while (true) {
            //向右判断
            x++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19) {
                right++;
                break;
            } else {
                break;
            }
        }//向右
        if (count == 2 && (left + right == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_attack(count, left + right, countTwo);

        //右倾斜方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左上判断
            y--;
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0 || y < 0) {
                leftUp++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右下判断
            x++;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19 || y >= 19) {
                rightDown++;
                break;
            } else {
                break;
            }
        }
        if (count == 2 && (leftUp + rightDown == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_attack(count, leftUp + rightDown, countTwo);

        //左倾斜方向判断
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左下判断
            x--;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x < 0 || y >= 19) {
                leftDown++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右上判断
            x++;
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if ((x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) || x >= 19 || y < 0) {
                rightUp++;
                break;
            } else {
                break;
            }
        }
        if (count == 2 && (leftDown + rightUp == 0)) {
            countTwo++;
            System.out.println("出现二连" + countTwo);
        }
        mark_medium_attack(count, leftDown + rightUp, countTwo);
    }

    /**
     * 初级难度电脑计算最适合的位置返回给computePos
     *
     * @param role  玩家颜色
     * @param chess 棋盘
     */
    public void countMaxLines_primary(int[][] chess, int role) {
        int comrole;
        if (role == Chess.black)
            comrole = Chess.white;
        else
            comrole = Chess.black;
        ChessCoord playerCoord = new ChessCoord();
        ChessCoord computerCoord = new ChessCoord();
        int x, y;
        for (x = 0; x < 19; x++) {
            for (y = 0; y < 19; y++) {
                if (chess[x][y] == Chess.noChess) {
                    countEveryPos_primary_defence(x, y, chess, role);
                    PlayerPointScore[x][y] = scores;
                    countEveryPos_primary_attack(x, y, chess, comrole);
                    ComputerPointScore[x][y] = scores;
                } else {
                    PlayerPointScore[x][y] = 0;
                    ComputerPointScore[x][y] = 0;
                }
            }
        }
        if (findBestPos(PlayerPointScore, playerCoord) >= findBestPos(ComputerPointScore, computerCoord)) {
            coord = playerCoord;
        } else {
            coord = computerCoord;
        }
    }

    /**
     * 寻找分数最大的点
     * 寻找分数最高的位置返回给countMaxLines_primary或countMaxLines_medium
     *
     * @param a 二维数组表示的在每个位置标记有分数的棋盘
     * @param c 用于接收最好位置的x，y值
     */
    public int findBestPos(int a[][], ChessCoord c) {
        int i, j, max = 0;

        for (i = 0; i <= 18; i++) {
            for (j = 0; j <= 18; j++) {
                if (a[i][j] > max) {
                    max = a[i][j];
                    c.setX(i);
                    c.setY(j);
                }
            }
        }
        return max;
    }

    /**
     * 初级难度电脑防守战略
     * 给每个空位置根据周围棋子的情况打防守分，分越大说明防守的必要性越高
     *
     * @param count 这个棋形有多少个棋子连在一起
     * @param i     有没有受到电脑棋子堵住，只有一端堵住i为1，两端都堵住i为2
     */
    public void mark_primary_defence(int count, int i) {
        if (count == 1) {
            scores = scores + 10;
        }
        //活二
        else if (count == 2 && i == 0) {
            scores = scores + 200;
        }
        //冲二
        else if (count == 2 && i == 1) {
            scores = scores + 50;
        }
        //活三
        else if (count == 3 && i == 0) {
            scores = scores + 15000;
            System.out.println("分数" + scores);
        }
        //冲三
        else if (count == 3 && i == 1) {
            scores = scores + 5000;
            System.out.println("分数" + scores);
        }
        //活四
        else if (count == 4 && i == 0) {
            scores = scores + 200000;
            System.out.println("分数" + scores);
        }
        //冲四
        else if (count == 4 && i == 1) {
            scores = scores + 140000;
            System.out.println("分数" + scores);
        } else if (count == 5) {
            scores = scores + 100000;
        }
    }

    /**
     * 中等难度电脑进攻战略
     * 根据每个空位置的周围棋子的情况打进攻分，分越高说明该点的进攻性越强
     *
     * @param count 这个棋形有多少个棋子连在一起
     * @param i     有没有受到电脑棋子堵住，只有一端堵住i为1，两端都堵住i为2
     */
    public void mark_primary_attack(int count, int i) {
        if (count == 1) {
            scores = scores + 10;
        }
        //活二
        else if (count == 2 && i == 0) {
            scores = scores + 200;
        }
        //冲二
        else if (count == 2 && i == 1) {
            scores = scores + 500;
        }
        //活三
        else if (count == 3 && i == 0) {
            scores = scores + 85000;
            System.out.println("分数" + scores);
        }
        //冲三
        else if (count == 3 && i == 1) {
            scores = scores + 35000;
            System.out.println("分数" + scores);
        }
        //活四
        else if (count == 4 && i == 0) {
            scores = scores + 990000;
            System.out.println("分数" + scores);
        }
        //冲四
        else if (count == 4 && i == 1) {
            scores = scores + 987000;
            System.out.println("分数" + scores);
        } else if (count == 5) {
            scores = scores + 100000;
        }
    }

    /**
     * 初级难度电脑防守战略
     * 统计玩家目前该位置对应的棋局情况,与中等电脑唯一的区别是不统计双二
     *
     * @param x     该位置的横坐标
     * @param y     该位置的纵坐标
     * @param chess int二维数组表示的棋盘
     * @param role  玩家棋子颜色
     */
    public void countEveryPos_primary_defence(int x, int y, int[][] chess, int role) {
        scores = 0;
        int matchRole, startX = x, startY = y, count = 0, up = 0, down = 0, left = 0, right = 0, leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0;
        if (role == Chess.black) {
            matchRole = Chess.white;
        } else {
            matchRole = Chess.black;
        }
        //竖直方向上判断输赢
        while (true) {
            //向上判断
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                up++;
                break;
            } else {
                break;
            }
        }
        y = startY;
        while (true) {
            //向下判断
            y = y + 1;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                down++;
                break;
            } else {
                break;
            }
        }
        mark_primary_defence(count, up + down);

        //水平方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左判断
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                left++;
                break;
            } else {
                break;
            }

        }
        x = startX;
        while (true) {
            //向右判断
            x++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                right++;
                break;
            } else {
                break;
            }
        }
        mark_primary_defence(count, left + right);

        //右倾斜方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左上判断
            y--;
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                leftUp++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右下判断
            x++;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                rightDown++;
                break;
            } else {
                break;
            }
        }
        mark_primary_defence(count, leftUp + rightDown);

        //左倾斜方向判断
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左下判断
            x--;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                leftDown++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右上判断
            x++;
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                rightUp++;
                break;
            } else {
                break;
            }
        }
        mark_primary_defence(count, leftDown + rightUp);
    }

    /**
     * 初级难度电脑进攻战略
     * 统计玩家目前该位置对应的棋局情况,与中级电脑唯一的区别是不统计双二
     *
     * @param x     该位置的横坐标
     * @param y     该位置的纵坐标
     * @param chess int二维数组表示的棋盘
     * @param role  电脑棋子颜色
     */
    public void countEveryPos_primary_attack(int x, int y, int[][] chess, int role) {
        scores = 0;
        int matchRole, startX = x, startY = y, count = 0, up = 0, down = 0, left = 0, right = 0, leftUp = 0, leftDown = 0, rightUp = 0, rightDown = 0;
        if (role == Chess.black) {
            matchRole = Chess.white;
        } else {
            matchRole = Chess.black;
        }
        //竖直方向上判断输赢
        while (true) {
            //向上判断
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                up++;
                break;
            } else {
                break;
            }
        }
        y = startY;
        while (true) {
            //向下判断
            y = y + 1;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                down++;
                break;
            } else {
                break;
            }
        }
        mark_primary_attack(count, up + down);

        //水平方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左判断
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                left++;
                break;
            } else {
                break;
            }

        }
        x = startX;
        while (true) {
            //向右判断
            x++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                right++;
                break;
            } else {
                break;
            }
        }
        mark_primary_attack(count, left + right);

        //右倾斜方向判断输赢
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左上判断
            y--;
            x--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                leftUp++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右下判断
            x++;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                rightDown++;
                break;
            } else {
                break;
            }
        }
        mark_primary_attack(count, leftUp + rightDown);

        //左倾斜方向判断
        x = startX;
        y = startY;
        count = 0;
        while (true) {
            //向左下判断
            x--;
            y++;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                leftDown++;
                break;
            } else {
                break;
            }
        }
        x = startX;
        y = startY;
        while (true) {
            //向右上判断
            x++;
            y--;
            if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == role) {
                count++;
            } else if (x >= 0 && x < 19 && y >= 0 && y < 19 && chess[x][y] == matchRole) {
                rightUp++;
                break;
            } else {
                break;
            }
        }
        mark_primary_attack(count, leftDown + rightUp);
    }

    /**
     * 高级难度电脑算法
     * 利用中等难度的统计分数的方法，对每个点的分数进行排序
     *
     * @param chess   int二维数组表示的棋盘
     * @param comrole 电脑棋子颜色
     */
    public List<Point> getSortList(int[][] chess, int comrole)//comrole是机器人颜色
    {
        int role = 0;//人类颜色
        List<Point> list = new ArrayList<Point>();
        if (comrole == Chess.white) {
            role = Chess.black;
        } else if (comrole == Chess.black) {
            role = Chess.black;
        }
        for (int i = 0; i < 19; i++) {
            for (int j = 0; j < 19; j++) {
                if (chess[i][j] == Chess.noChess) {
                    countEveryPos_medium_attack(i, j, chess, comrole);
                    int attacks = scores;
                    countEveryPos_medium_defence(i, j, chess, role);
                    int defence = scores;
                    Point a = new Point();
                    a.setAttack(attacks);
                    a.setDefence(defence);
                    a.setSum(attacks + defence);
                    a.setX(i);
                    a.setY(j);
                    list.add(a);
                }
            }
        }
        Collections.sort(list);

        return list;
    }

    /**
     * 高级难度电脑算法
     * 博弈树alpha-beta剪枝搜索算法
     *
     * @param chess int二维数组表示的棋盘
     * @param depth 搜索树的深度
     * @param role  初始调用时传入的时电脑颜色
     * @param alpha 为已知的最大值，初始传入时设为默认-maxint
     * @param beta  为已知的最小值，初始传入时设为默认maxint
     */
    public int getValueByTrees(int depth, int role, int[][] chess, int alpha, int beta)//alpha可以视作自己，beta可以视作电脑？好像是这样
    {
        int[][] tempchess = new int[19][19];
        for (int i = 0; i <= 18; i++) {
            for (int j = 0; j <= 18; j++) {
                tempchess[i][j] = chess[i][j];
            }
        }
        List<Point> orderlist = getSortList(tempchess, role);
        if (depth == 3)//搜索深度默认为3层
        {
            return orderlist.get(0).getSum();
        }
        for (int i = 0; i < 5; i++) {
            Point temp = orderlist.get(0);
            int score;
            if (temp.getSum() > 900000) {//大于活4
                score = temp.getSum();
            } else {
                int oprole;
                if (role == Chess.black) {
                    oprole = Chess.white;
                } else {
                    oprole = Chess.black;
                }

                // 这个步骤是模拟下棋
                tempchess[temp.getX()][temp.getY()] = role;
                score = getValueByTrees(depth + 1, oprole, tempchess, alpha, beta);
            }
            if (depth % 2 == 0) {
                // 自己，找最大值
                if (score > alpha) {
                    alpha = score;
                    if (depth == 0) {
                        // 结果
                        pointfortree = temp;
                        // System.out.println(chessBeansForTree);
                    }
                }
                if (alpha >= beta) {
                    score = alpha;
                    return score;
                }
            } else {
                if (score < beta) {
                    beta = score;
                }
                if (alpha >= beta) {
                    score = beta;
                    return score;
                }
            }
        }
        return depth % 2 == 0 ? alpha : beta;
    }

    /**
     * 高级难度电脑算法
     * 是computePos函数进入高级电脑的算法入口
     *
     * @param chess int二维数组表示的棋盘
     * @param role  初始调用时传入的时电脑颜色
     */
    public void countMaxLines_senior(int[][] chess, int role) {
        Point bean;
        getValueByTrees(0, role, chess, -Integer.MAX_VALUE, Integer.MAX_VALUE);
        bean = pointfortree;
        int x = bean.getX();
        int y = bean.getY();
        coord.setX(x);
        coord.setY(y);
    }
}
